bitkeeper revision 1.1108.33.30 (410e5661Rzjfq990tCgPcsBrf4HUgg)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 2 Aug 2004 14:57:37 +0000 (14:57 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 2 Aug 2004 14:57:37 +0000 (14:57 +0000)
Change dom_mem_op interface to allow non-order-0 allocations.
(i.e., can alloc contiguous memory extents larger than one page).

linux-2.4.26-xen-sparse/arch/xen/drivers/balloon/balloon.c
linux-2.6.7-xen-sparse/arch/xen/i386/mm/hypervisor.c
linux-2.6.7-xen-sparse/drivers/xen/netback/netback.c
linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h
xen/common/dom_mem_ops.c

index cb94867902b28b9a6b465b46df63726376721ec9..dba26c9c805be1051c84dfd633226fd9a04b9d4e 100644 (file)
@@ -109,7 +109,7 @@ static unsigned long inflate_balloon(unsigned long num_pages)
     XEN_flush_page_update_queue();
 
     ret = HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, 
-                                parray, num_pages);
+                                parray, num_pages, 0);
     if ( unlikely(ret != num_pages) )
     {
         printk("Unable to inflate balloon, error %lx\n", ret);
@@ -199,7 +199,7 @@ unsigned long deflate_balloon(unsigned long num_pages)
     XEN_flush_page_update_queue();
 
     ret = HYPERVISOR_dom_mem_op(MEMOP_increase_reservation, 
-                                parray, num_pages);
+                                parray, num_pages, 0);
     if ( unlikely(ret != num_pages) )
     {
         printk("Unable to deflate balloon, error %lx\n", ret);
index f48547197be8a923f7d760c55434d90a20267cb4..fc7bc3e523da03fa474e2223815a6a605b4ee862 100644 (file)
@@ -305,7 +305,7 @@ unsigned long allocate_empty_lowmem_region(unsigned long pages)
     flush_page_update_queue();
 
     ret = HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, 
-                                pfn_array, 1<<order);
+                                pfn_array, 1<<order, 0);
     if ( unlikely(ret != (1<<order)) )
     {
         printk(KERN_WARNING "Unable to reduce memory reservation (%d)\n", ret);
@@ -332,7 +332,7 @@ void deallocate_lowmem_region(unsigned long vstart, unsigned long pages)
         BUG();
 
     ret = HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
-                                pfn_array, 1<<order);
+                                pfn_array, 1<<order, 0);
     if ( unlikely(ret != (1<<order)) )
     {
         printk(KERN_WARNING "Unable to increase memory reservation (%d)\n",
index c0381048d8bea99c86e22ddbed13c2a44e7dc82d..6f924625291aaba9c440a154bceb264312e5cc34 100644 (file)
@@ -71,7 +71,7 @@ static spinlock_t mfn_lock = SPIN_LOCK_UNLOCKED;
 static void __refresh_mfn_list(void)
 {
     int ret = HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
-                                    mfn_list, MAX_MFN_ALLOC);
+                                    mfn_list, MAX_MFN_ALLOC, 0);
     if ( unlikely(ret != MAX_MFN_ALLOC) )
         BUG();
     alloc_index = MAX_MFN_ALLOC;
@@ -94,7 +94,8 @@ static void dealloc_mfn(unsigned long mfn)
     spin_lock_irqsave(&mfn_lock, flags);
     if ( alloc_index != MAX_MFN_ALLOC )
         mfn_list[alloc_index++] = mfn;
-    else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, &mfn, 1) != 1 )
+    else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,
+                                    &mfn, 1, 0) != 1 )
         BUG();
     spin_unlock_irqrestore(&mfn_lock, flags);
 }
index db275cbd21fb8e9074246a9e666b2e94b872ff8d..1c55f2cb442eb5ddfbf95ddf67a92d19972f0426 100644 (file)
@@ -282,6 +282,7 @@ static void network_alloc_rx_buffers(struct net_device *dev)
     rx_mcl[nr_pfns].args[0] = MEMOP_decrease_reservation;
     rx_mcl[nr_pfns].args[1] = (unsigned long)rx_pfn_array;
     rx_mcl[nr_pfns].args[2] = (unsigned long)nr_pfns;
+    rx_mcl[nr_pfns].args[3] = 0;
 
     /* Zap PTEs and give away pages in one big multicall. */
     (void)HYPERVISOR_multicall(rx_mcl, nr_pfns+1);
index 0a536b9fe8573cdf85df4c2c54000884589e65bf..9909a2c466b493c51107a6097c308c19bb53b253 100644 (file)
@@ -3,7 +3,7 @@
  * 
  * Linux-specific hypervisor handling.
  * 
- * Copyright (c) 2002, K A Fraser
+ * Copyright (c) 2002-2004, K A Fraser
  */
 
 #ifndef __HYPERVISOR_H__
@@ -366,14 +366,16 @@ static inline int HYPERVISOR_set_fast_trap(int idx)
 }
 
 static inline int HYPERVISOR_dom_mem_op(unsigned int   op,
-                                        unsigned long *pages,
-                                        unsigned long  nr_pages)
+                                        unsigned long *extent_list,
+                                        unsigned long  nr_extents,
+                                        unsigned int   extent_order)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
-        "b" (op), "c" (pages), "d" (nr_pages) : "memory" );
+        "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order)
+        : "memory" );
 
     return ret;
 }
index d11e1fe0dd780629b93e95450d8fb7ab72f6c3f9..e2a330ae96ca39be05197d169dfeedefb8630ef8 100644 (file)
 #include <asm/domain_page.h>
 
 static long alloc_dom_mem(struct domain *d, 
-                          unsigned long *pages, 
-                          unsigned long  nr_pages)
+                          unsigned long *extent_list, 
+                          unsigned long  nr_extents,
+                          unsigned int   extent_order)
 {
     struct pfn_info *page;
     unsigned long    i;
 
-    for ( i = 0; i < nr_pages; i++ )
+    if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current) )
     {
-        if ( unlikely((page = alloc_domheap_page(d)) == NULL) )
+        DPRINTK("Only I/O-capable domains may allocate > order-0 memory.\n");
+        return 0;
+    }
+
+    for ( i = 0; i < nr_extents; i++ )
+    {
+        if ( unlikely((page = alloc_domheap_pages(d, extent_order)) == NULL) )
         {
             DPRINTK("Could not allocate a frame\n");
-            break;
+            return i;
         }
 
         /* Inform the domain of the new page's machine address. */ 
-        if ( unlikely(put_user(page_to_pfn(page), &pages[i]) != 0) )
-            break;
+        if ( unlikely(put_user(page_to_pfn(page), &extent_list[i]) != 0) )
+            return i;
     }
 
     return i;
 }
     
-static long free_dom_mem(struct domain *d, 
-                         unsigned long *pages, 
-                         unsigned long  nr_pages)
+static long free_dom_mem(struct domain *d,
+                         unsigned long *extent_list, 
+                         unsigned long  nr_extents,
+                         unsigned int   extent_order)
 {
     struct pfn_info *page;
-    unsigned long    i, mpfn;
-    long             rc = 0;
+    unsigned long    i, j, mpfn;
 
-    for ( i = 0; i < nr_pages; i++ )
+    for ( i = 0; i < nr_extents; i++ )
     {
-        if ( unlikely(get_user(mpfn, &pages[i]) != 0) )
-            break;
-
-        if ( unlikely(mpfn >= max_page) )
-        {
-            DPRINTK("Domain %u page number out of range (%08lx>=%08lx)\n", 
-                    d->domain, mpfn, max_page);
-            rc = -EINVAL;
-            break;
-        }
+        if ( unlikely(get_user(mpfn, &extent_list[i]) != 0) )
+            return i;
 
-        page = &frame_table[mpfn];
-        if ( unlikely(!get_page(page, d)) )
+        for ( j = 0; j < (1 << extent_order); j++ )
         {
-            DPRINTK("Bad page free for domain %u\n", d->domain);
-            rc = -EINVAL;
-            break;
-        }
+            if ( unlikely((mpfn + j) >= max_page) )
+            {
+                DPRINTK("Domain %u page number out of range (%08lx>=%08lx)\n", 
+                        d->domain, mpfn + j, max_page);
+                return i;
+            }
+            
+            page = &frame_table[mpfn + j];
+            if ( unlikely(!get_page(page, d)) )
+            {
+                DPRINTK("Bad page free for domain %u\n", d->domain);
+                return i;
+            }
 
-        if ( test_and_clear_bit(_PGC_guest_pinned, &page->u.inuse.count_info) )
-            put_page_and_type(page);
+            if ( test_and_clear_bit(_PGC_guest_pinned, 
+                                    &page->u.inuse.count_info) )
+                put_page_and_type(page);
+            
+            if ( test_and_clear_bit(_PGC_allocated,
+                                    &page->u.inuse.count_info) )
+                put_page(page);
 
-        if ( test_and_clear_bit(_PGC_allocated, &page->u.inuse.count_info) )
             put_page(page);
-
-        put_page(page);
+        }
     }
 
-    return rc ? rc : nr_pages;
+    return i;
 }
     
-long do_dom_mem_op(unsigned int op, void *pages, unsigned long nr_pages)
+long do_dom_mem_op(unsigned int   op, 
+                   unsigned long *extent_list, 
+                   unsigned long  nr_extents,
+                   unsigned int   extent_order)
 {
     if ( op == MEMOP_increase_reservation )
-        return alloc_dom_mem(current, pages, nr_pages);
+        return alloc_dom_mem(current, extent_list, nr_extents, extent_order);
 
     if ( op == MEMOP_decrease_reservation )
-        return free_dom_mem(current, pages, nr_pages);
+        return free_dom_mem(current, extent_list, nr_extents, extent_order);
 
     return -ENOSYS;
 }